package de.sendorian.util.matcher;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeDiagnosingMatcher;


public class FileTypeMatchers {

    private static final List<String> archiveExtensions = new ArrayList<String>();

    private static final List<String> ignoredFiles = new ArrayList<String>();

    static {
        archiveExtensions.add(".zip");
        archiveExtensions.add(".rar");
        archiveExtensions.add(".gzip");
        archiveExtensions.add(".gz");
        archiveExtensions.add(".tar");
        archiveExtensions.add(".7z");

        ignoredFiles.add("__MACOSX");
        ignoredFiles.add("._");
        ignoredFiles.add(".DS_Store");
        ignoredFiles.add("Desktop.ini");
    }


    @Factory
    public static Matcher<String> archive() {
        return new TypeSafeDiagnosingMatcher<String>() {
            String fileTested;


            @Override
            public boolean matchesSafely(String item, Description mismatchDescription) {
                fileTested = item;
                for (String archiveExtension : archiveExtensions) {
                    if (StringUtils.endsWithIgnoreCase(item, archiveExtension))
                        return true;
                }
                return false;
            }


            public void describeTo(Description description) {
                description.appendText(" that ");
                description.appendValue(fileTested);
                description.appendText("is an archive");
            }
        };
    }


    /**
     * Files and folders created by OSX or Windows that can be ignored.
     * 
     */
    @Factory
    public static Matcher<String> ignoredFiles() {
        return new BlacklistMatcher<String>(ignoredFiles) {
            @Override
            protected boolean matchesInternal(String objectToCompare, Object unwantedObject) {
                return objectToCompare.startsWith((String) unwantedObject);
            }
        };
    }

}
